home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / dbu / pr_tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-18  |  9.4 KB  |  619 lines

  1. # include    <symbol.h>
  2. # include    <ingres.h>
  3. # include    <tree.h>
  4. # include    <aux.h>
  5. # include    <sccs.h>
  6.  
  7. SCCSID(@(#)pr_tree.c    8.3    5/1/86)
  8.  
  9. /*
  10. **  PR_TREE.C -- Query tree printing routines
  11. **
  12. **    Trace Flags:
  13. **        52
  14. */
  15.  
  16.  
  17.  
  18.  
  19. char    *pr_trim();
  20. char    *resultres();
  21.  
  22. struct tab
  23. {
  24.     char    t_opcode;
  25.     char    *t_string;
  26. };
  27.  
  28.  
  29. struct tab    Uop_tab[] =
  30. {
  31.     opPLUS,        "+ ",
  32.     opMINUS,    "- ",
  33.     opNOT,        "not[ERROR]",
  34.     opATAN,        "atan",
  35.     opCOS,        "cos",
  36.     opGAMMA,    "gamma",
  37.     opLOG,        "log",
  38.     opASCII,    "ascii",
  39.     opSIN,        "sin",
  40.     opSQRT,        "sqrt",
  41.     opABS,        "abs",
  42.     opEXP,        "exp",
  43.     opINT1,        "int1",
  44.     opINT2,        "int2",
  45.     opINT4,        "int4",
  46.     opFLOAT4,    "float4",
  47.     opFLOAT8,    "float8",
  48. };
  49. struct tab    Bop_tab[] =
  50. {
  51.     opADD,        "+",
  52.     opSUB,        "-",
  53.     opMUL,        "*",
  54.     opDIV,        "/",
  55.     opPOW,        "**",
  56.     opEQ,        "=",
  57.     opNE,        "!=",
  58.     opLT,        "<",
  59.     opLE,        "<=",
  60.     opGT,        ">",
  61.     opGE,        ">=",
  62.     opMOD,        "%",
  63. };
  64.  
  65. struct tab    Cop_tab[] =
  66. {
  67.     opDBA,        "dba",
  68.     opUSERCODE,    "usercode",
  69.     opDATE,        "date",
  70.     opTIME,        "time",
  71. };
  72.  
  73. struct tab    Aop_tab[] =
  74. {
  75.     opCOUNT,    "count",
  76.     opCOUNTU,    "countu",
  77.     opSUM,        "sum",
  78.     opSUMU,        "sumu",
  79.     opAVG,        "avg",
  80.     opAVGU,        "avgu",
  81.     opMIN,        "min",
  82.     opMAX,        "max",
  83.     opANY,        "any",
  84. };
  85.  
  86.  
  87. DESC        Attdes;
  88. int        Tl_elm;
  89. int        Dom_num;
  90. char        *Resrel;
  91. /* 
  92. **  PR_TREE
  93. **
  94. **    tree:    tl_clause ROOT tl_clause
  95. **
  96. **    prints out a tree assuming a mdVIEW-like mode
  97. **
  98. */
  99.  
  100. pr_tree(root)
  101. QTREE    *root;
  102. {
  103.  
  104. #    ifdef xZTR1
  105.     if (tTf(52, -1))
  106.         printf("pr_tree: root %u Resultvar %d Resrel %s\n",
  107.             root, Qt.qt_resvar, Resrel);
  108. #    endif
  109.  
  110.     printf("%s ", pr_trim(resultres(), MAXNAME));
  111.  
  112.     pr_dom_init();
  113.     Tl_elm = 0;
  114.  
  115.     /* print target list */
  116.     printf("(\n");
  117.     pr_tl_clause(root->left, TRUE);
  118.     putchar(')');
  119.  
  120.     /* print qualification */
  121.     if (root->right->sym.type != QLEND)
  122.     {
  123.                 printf("\nwhere ");
  124.         pr_qual(root->right);
  125.     }
  126.     putchar('\n');
  127. }
  128. /*
  129. **  PR_TL_CLAUSE
  130. **
  131. **    tl_clause:    TREE
  132. **        |    tl_clause RESDOM expr
  133. **    
  134. ** target_flag = "in a target list (as opposed to in a by list)"
  135. */
  136.  
  137. pr_tl_clause(t_l, target_flag)
  138. QTREE        *t_l;
  139. register bool    target_flag;
  140. {
  141.  
  142. #    ifdef xZTR1
  143.     if (tTf(52, 1))
  144.         printf("tl_clause target %d Tl_elm %d\n", target_flag, Tl_elm);
  145. #    endif
  146.  
  147.     if (t_l->sym.type != TREE)
  148.     {
  149.         pr_tl_clause(t_l->left, target_flag);
  150.         if (Tl_elm)
  151.         {
  152.             printf(", ");
  153.             if (target_flag)
  154.                 putchar('\n');
  155.         }
  156.         /* print out info on result variable */
  157.         pr_resdom(t_l, target_flag);
  158.         pr_expr(t_l->right);
  159.         Tl_elm++;
  160.     }
  161. }
  162. /*
  163. **  PR_RESDOM
  164. **
  165. **    print out info on a result attribute.
  166. **    this will be done only if the RESDOM node
  167. **    is inside a target_list and if the Qt.qt_resvar >= 0.
  168. **    Qt.qt_resvar == -1 inside a target list indicates that this is
  169. **    a retrieve to terminal.
  170. */
  171.  
  172. pr_resdom(resdom, target_flag)
  173. QTREE    *resdom;
  174. int    target_flag;
  175. {
  176.  
  177. #    ifdef xZTR1
  178.     if (tTf(52, 2))
  179.         printf("pr_resdom: target_flag %d\n", target_flag);
  180. #    endif
  181.  
  182.     if (target_flag)
  183.     {
  184.         printf("\t");
  185.         pr_attname(resultres(), resdom->sym.value.sym_resdom.resno);
  186.         printf(" = ");
  187.     }
  188. }
  189. /* 
  190. **  PR_ATTNAME
  191. **
  192. **    give a relation name, and the attribute number of that
  193. **    relation, looks in the attribute relation for the name of the
  194. **    attribute.
  195. */
  196.  
  197. pr_attname(rel, attno)
  198. char    *rel;
  199. int    attno;
  200. {
  201.     TID            tid;
  202.     struct attribute    key, tuple;
  203.     short            attnum;
  204.     register        i;
  205.  
  206. #    ifdef xZTR1
  207.     if (tTf(52, 3))
  208.         printf("pr_attname: rel %s attno %d\n",
  209.         rel, attno);
  210. #    endif
  211.  
  212.     if (attno == 0)
  213.     {
  214.         printf("tid");
  215.         return;
  216.     }
  217.     opencatalog("attribute", OR_READ);
  218.     clearkeys(&Attdes);
  219.     attnum = (short) attno;
  220.     setkey(&Attdes, &key, rel, ATTRELID);
  221.     setkey(&Attdes, &key, &attnum, ATTID);
  222.     i = getequal(&Attdes, &key, &tuple, &tid);
  223.     if (i)
  224.         syserr("pr_attname: bad getequal %d rel %s attno %d",
  225.         i, rel, attno);
  226.     printf("%s", pr_trim(tuple.attname, MAXNAME));
  227. }
  228. /*
  229. **  PR_EXPR
  230. **
  231. **    expr:        VAR
  232. **        |    expr BOP expr
  233. **        |    expr UOP
  234. **        |    AOP AGHEAD qual
  235. **              \
  236. **               expr
  237. **        |    BYHEAD      AGHEAD qual
  238. **                /    \
  239. **        tl_clause     AOP
  240. **                \
  241. **                 expr
  242. **        |    INT
  243. **        |    FLOAT
  244. **        |     CHAR
  245. */
  246.  
  247. pr_expr(e)
  248. register QTREE    *e;
  249. {
  250.     register int    op;
  251.     register int    tl_elm;
  252.  
  253.     switch (e->sym.type)
  254.     {
  255.       case VAR:
  256.         pr_var(e);
  257.         break;
  258.  
  259.       case BOP:
  260.         if (e->sym.value.sym_op.opno == opCONCAT)
  261.         {
  262.             printf("concat(");
  263.             pr_expr(e->left);
  264.             printf(", ");
  265.             pr_expr(e->right);
  266.             putchar(')');
  267.         }
  268.         else
  269.         {
  270.             putchar('(');
  271.             pr_expr(e->left);
  272.             pr_op(BOP, e->sym.value.sym_op.opno);
  273.             pr_expr(e->right);
  274.             putchar(')');
  275.         }
  276.         break;
  277.  
  278.       case UOP:
  279.         if ((op = e->sym.value.sym_op.opno) == opMINUS || op == opPLUS || op == opNOT)
  280.         {
  281.             pr_op(UOP, e->sym.value.sym_op.opno);
  282.             pr_expr(e->left);
  283.             putchar(')');
  284.         }
  285.         else
  286.         {
  287.             /* functional operators */
  288.             pr_op(UOP, e->sym.value.sym_op.opno);
  289.             pr_expr(e->left);
  290.             putchar(')');
  291.         }
  292.         break;
  293.  
  294.       case AGHEAD:
  295.         if (e->left->sym.type == AOP)
  296.         {
  297.             /* simple aggregate */
  298.             pr_op(AOP, e->left->sym.value.sym_op.opno);
  299.             pr_expr(e->left->right);
  300.             if (e->right->sym.type != QLEND)
  301.             {
  302.                 printf("\\where ");
  303.                 pr_qual(e->right);
  304.             }
  305.             putchar(')');
  306.         }
  307.         else
  308.         {
  309.             /* aggregate function */
  310.             pr_op(AOP, e->left->right->sym.value.sym_op.opno);
  311.             pr_expr(e->left->right->right);
  312.             printf(" by ");
  313.             /* avoid counting target list elements
  314.              * in determining wether to put out
  315.              * commas after list's elements
  316.              */
  317.             tl_elm = Tl_elm;
  318.             Tl_elm = 0;
  319.             pr_tl_clause(e->left->left, FALSE);
  320.             Tl_elm = tl_elm;
  321.             if (e->right->sym.type != QLEND)
  322.             {
  323.                 printf("\n\t\twhere ");
  324.                 pr_qual(e->right);
  325.             }
  326.             putchar(')');
  327.         }
  328.         break;
  329.       
  330.       case INT:
  331.       case FLOAT:
  332.       case CHAR:
  333.         pr_const(e);
  334.         break;
  335.  
  336.       default:
  337.         syserr("expr %d", e->sym.type);
  338.     }
  339. }
  340. /*
  341. **  PR_CONST -- print constant
  342. */
  343.  
  344. pr_const(c)
  345. register QTREE    *c;
  346. {
  347.     register char    *cp;
  348.     register int    i;
  349.     char        ch;
  350.     double        d;
  351.  
  352.     switch (c->sym.type)
  353.     {
  354.       case INT:
  355.         if (c->sym.len == 1)
  356.             printf("%d", c->sym.value.sym_data.i1type);
  357.         else if (c->sym.len == 2)
  358.             printf("%d", c->sym.value.sym_data.i2type);
  359.         else    /* i4 */
  360.             printf("%D", c->sym.value.sym_data.i4type);
  361.         break;
  362.  
  363.       case FLOAT:
  364.         if (c->sym.len == 4)
  365.             d = c->sym.value.sym_data.f4type;
  366.         else
  367.             d = c->sym.value.sym_data.f8type;
  368.         printf("%-10.3f", d);
  369.         break;
  370.  
  371.       case CHAR:
  372.         printf("\"");
  373.         cp = c->sym.value.sym_data.c0type;
  374.         for (i = c->sym.len; i--; cp++)
  375.         {
  376.             if (any(*cp, "\"\\[]*?") == TRUE)
  377.                 putchar('\\');
  378.  
  379.             if (*cp >= ' ')
  380.             {
  381.                 putchar(*cp);
  382.                 continue;
  383.             }
  384.             /* perform pattern matching character replacement */
  385.             switch (*cp)
  386.             {
  387.               case PAT_ANY:
  388.                 ch = '*';
  389.                 break;
  390.             
  391.               case PAT_ONE:
  392.                 ch = '?';
  393.                 break;
  394.             
  395.               case PAT_LBRAC:
  396.                 ch = '[';
  397.                 break;
  398.  
  399.               case PAT_RBRAC:
  400.                 ch = ']';
  401.                 break;
  402.  
  403.               default:
  404.                 ch = *cp;
  405.             }
  406.             putchar(ch);
  407.         }
  408.         putchar('"');
  409.         break;
  410.  
  411.       default:
  412.         syserr("bad constant %d", c->sym.type);
  413.     }
  414. }
  415. /*
  416. **  PR_OP -- print out operator of a certain type
  417. */
  418.  
  419. pr_op(op_type, op_code)
  420. int        op_type;
  421. register int    op_code;
  422. {
  423.     register struct tab    *s;
  424.  
  425.     switch (op_type)
  426.     {
  427.       case UOP:
  428.         s = &Uop_tab[op_code];
  429.         printf("%s(", s->t_string);
  430.         break;
  431.  
  432.       case BOP:
  433.         s = &Bop_tab[op_code];
  434.         printf(" %s ", s->t_string);
  435.         break;
  436.  
  437.       case AOP:
  438.         s = &Aop_tab[op_code];
  439.         printf("%s(", s->t_string);
  440.         break;
  441.  
  442.       case COP:
  443.         s = &Cop_tab[op_code];
  444.         printf("%s", s->t_string);
  445.         break;
  446.     }
  447.     if (op_code != s->t_opcode)
  448.         syserr("pr_op: op in wrong place type %d, code %d", op_type,
  449.         s->t_opcode);
  450. }
  451. /*
  452. **  PR_VAR
  453. **
  454. **    print a VAR node: that is, a var.attno pair
  455. **    at present the var part is the relation name over which var
  456. **    ranges.
  457. */
  458.  
  459. pr_var(var)
  460. QTREE    *var;
  461. {
  462.  
  463. #    ifdef xZTR1
  464.     if (tTf(52, 4))
  465.         printf("pr_var(var=%d)\n", var);
  466. #    endif
  467.     pr_rv(var->sym.value.sym_var.varno);
  468.     putchar('.');
  469.     pr_attname(Qt.qt_rangev[var->sym.value.sym_var.varno].rngvdesc->reldum.relid, var->sym.value.sym_var.attno);
  470. }
  471. /*
  472. **  PR_QUAL
  473. **
  474. **    qual:        QLEND
  475. **        |    q_clause AND qual
  476. **
  477. */
  478.  
  479. pr_qual(q)
  480. register QTREE    *q;
  481. {
  482.  
  483.     pr_q_clause(q->left);
  484.     if (q->right->sym.type != QLEND)
  485.     {
  486.         printf(" and ");
  487.         pr_qual(q->right);
  488.     }
  489. }
  490. /*
  491. **  PR_Q_CLAUSE
  492. **
  493. **    q_clause:    q_clause OR q_clause
  494. **        |    expr
  495. */
  496.  
  497. pr_q_clause(q)
  498. QTREE    *q;
  499. {
  500.  
  501.     if (q->sym.type == OR)
  502.     {
  503.         pr_q_clause(q->left);
  504.         printf(" or ");
  505.         pr_q_clause(q->right);
  506.     }
  507.     else
  508.         pr_expr(q);
  509. }
  510. /*
  511. **  PR_TRIM
  512. */
  513.  
  514. char *
  515. pr_trim(s, l)
  516. register char    *s;
  517. register int    l;
  518. {
  519.     static char    buf[30];
  520.  
  521.     bmove(s, buf, l);
  522.     for (s = buf; l && *s != ' ' && *s; --l)
  523.         s++;
  524.     *s = '\0';
  525.     return (buf);
  526. }
  527. /*
  528. **  PR_DOM_INIT
  529. */
  530.  
  531. pr_dom_init()
  532. {
  533.     Dom_num = 0;
  534. }
  535.  
  536. pr_ddom()
  537. {
  538.     printf("d%d = ", Dom_num++);
  539. }
  540. /*
  541. **  PR_RANGE -- print the range table
  542. */
  543.  
  544. pr_range()
  545. {
  546.     register int    i;
  547.  
  548.     for (i = 0; i <= MAXVAR; i++)
  549.     {
  550.         if (Qt.qt_rangev[i].rngvdesc != NULL)
  551.         {
  552.             printf("range of ");
  553.             pr_rv(i);
  554.             printf(" is %s\n", 
  555.               pr_trim(Qt.qt_rangev[i].rngvdesc->reldum.relid, MAXNAME));
  556.         }
  557.     }
  558. }
  559. /*
  560. **  PR_RV -- print range variable
  561. */
  562.  
  563. pr_rv(re)
  564. register int    re;
  565. {
  566.     register int    j;
  567.     register char    ch;
  568.  
  569.     ch = Qt.qt_rangev[re].rngvdesc->reldum.relid[0];
  570.  
  571. #    ifdef xZTR1
  572.     if (tTf(52, 6))
  573.         printf("pr_rv(%d) ch '%c'\n", re, ch);
  574. #    endif
  575.     
  576.     for (j = 0; j <= MAXVAR; j++)
  577.     {
  578.         if (Qt.qt_rangev[j].rngvdesc == NULL)
  579.             continue;
  580.         if (ch == Qt.qt_rangev[j].rngvdesc->reldum.relid[0])
  581.             break;
  582.     }
  583.     if (j < re)
  584.         printf("rv%d", re);
  585.     else
  586.         printf("%c", ch);
  587. }
  588. /*
  589. **  RESULTRES
  590. */
  591.  
  592. char *
  593. resultres()
  594. {
  595.     extern char    *Resrel;
  596.  
  597. #    ifdef xZTR1
  598.     if (tTf(52, 5))
  599.         printf("resultres: Resultvar %d, Resrel %s\n", Qt.qt_resvar, Resrel);
  600. #    endif
  601.     if (Qt.qt_resvar > 0)
  602.         return (Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relid);
  603.     if (Resrel == 0)
  604.         syserr("resultres: Resrel == 0");
  605.  
  606.     return (Resrel);
  607. }
  608.  
  609. any(c, s)
  610. register char    c;
  611. register char    *s;
  612. {
  613.  
  614.     while (*s != '\0')
  615.         if (*s++ == c)
  616.             return (TRUE);
  617.     return (FALSE);
  618. }
  619.